/*
 *  test/clear_left_recursion.c
 *
 *  Harry Wei <harryxiyou@gmail.com> 2012 (C) 
 *
 *  Write for Yuanzhen Kong for his LL(1) syntactic parser
 */

/*
 *  G[S]:
 *  T --> T,d | a
 *  
 *  G[S]:
 *  T --> aM
 *  M--> ,dE|E
 */
#include <stdio.h>
#include <string.h>

#define BUF_LEN			(100)

/* 
 * clear_left_recursion: clear a production's left recursion 
 * @para production: The production for parser
 * @para result: Keep the result after clear recursion
 * @return value: 0 is right, -1 is wrong 
 * XXX some bugs exists, so it now can only deal a few conditions
 */
static int clear_left_recursion(char *production, char *result) {
	int i = 2;
	char tmp[BUF_LEN];
	char ch = 'M';

	memset(tmp, '\0',BUF_LEN);
	if (NULL == production || NULL == result) {
		printf("%s -- Parameter Error!", __func__);
		return -1;
	}
	if (production[0] == production[1]) { /* Production has left recursion */
		while (1) {
			if ('|' == production[i]) {
				sprintf(result, "%s%s%c", result, "E|E", '$');
				sprintf(result, "%s%c", result, production[0]);
				i++; 
			}
			if ('$' == production[i]) { 
				sprintf(result, "%s%c%c", result, result[0], '$');
				break;
			}
			if (2 == i) {
				sprintf(result, "%c", ch);
				sprintf(result, "%s%c", result, production[i]);
			} else {
				sprintf(result, "%s%c", result, production[i]);
			}
			i++;
		}
	}
	return 0;
}

/* For test Use */
int main(int argc, char **argv) {
	int ret = 0;
	char production[] = "TT,d|a$"; /* $ is the end sign of a production */ 
	char result[BUF_LEN];

	memset(result, '\0', BUF_LEN);
	ret = clear_left_recursion(production, result);
	printf("Test result is %s\n", result);
	return 0;
}
